home *** CD-ROM | disk | FTP | other *** search
/ IRIX 6.3 Development Libraries / SGI IRIX 6.3 Development Libraries.iso / dist6.3 / gl_dev.idb / usr / share / src / OpenGL / demos / ideas / track.c.z / track.c
Encoding:
C/C++ Source or Header  |  1996-12-06  |  22.8 KB  |  1,005 lines

  1. #include <math.h>
  2. #include <sys/time.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include "objects.h"
  6. #include <GL/glut.h>
  7.  
  8. #define X 0
  9. #define Y 1
  10. #define Z 2
  11.  
  12. #ifndef TRUE
  13. #define TRUE 1
  14. #endif
  15. #ifndef FALSE
  16. #define FALSE 0
  17. #endif
  18.  
  19. #define DEG *M_PI/180.0
  20. #define RAD *180.0/M_PI
  21.  
  22. float move_speed;        /* Spline distance per second */
  23.  
  24. int multisample = 0;        /* Antialias polygons? */
  25. int doublebuffer = 1;        /* Doublebuffer? */
  26.  
  27.  
  28. #define SPEED_SLOW        0.2    /* Spline distances per second */
  29. #define SPEED_MEDIUM        0.4
  30. #define SPEED_FAST        0.7
  31. #define SPEED_SUPER_FAST    1.0
  32.  
  33. #define O_NOMS        7
  34. #define O_4MS        8
  35. #define O_8MS        9
  36. #define O_16MS        10
  37.  
  38. static int RGBA_SB_attributes = GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH;
  39.  
  40. static int RGBA_SB_ST_attributes = GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STEREO;
  41.  
  42. static int RGBA_DB_attributes = GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH;
  43.  
  44. static int RGBA_DB_ST_attributes = GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STEREO;
  45.  
  46. float idmat[4][4] = {
  47.     {1.0, 0.0, 0.0, 0.0},
  48.     {0.0, 1.0, 0.0, 0.0},
  49.     {0.0, 0.0, 1.0, 0.0},
  50.     {0.0, 0.0, 0.0, 1.0},
  51. };
  52.  
  53. float light1_ambient[] = { 0.0,0.0,0.0,1.0 };
  54. float light1_lcolor[] = { 1.0,1.0,1.0,1.0 };
  55. float light1_position[] = { 0.0,1.0,0.0,0.0 };
  56.  
  57. float light2_ambient[] = { 0.0,0.0,0.0,1.0 };
  58. float light2_lcolor[] = { 0.3,0.3,0.5,1.0 };
  59. float light2_position[] = { -1.0,0.0,0.0,0.0 };
  60.  
  61. float light3_ambient[] = { 0.2,0.2,0.2,1.0 };
  62. float light3_lcolor[] = { 0.2,0.2,0.2,1.0 };
  63. float light3_position[] = { 0.0,-1.0,0.0,0.0 };
  64.  
  65. float lmodel_LVW[] = { 0.0 };
  66. float lmodel_ambient[] = { 0.3,0.3,0.3,1.0 };
  67. float lmodel_TWO[] = { GL_TRUE };
  68.  
  69. float mat_logo_ambient[] = {0.1, 0.1, 0.1, 1.0};
  70. float mat_logo_diffuse[] = {0.5, 0.4, 0.7, 1.0};
  71. float mat_logo_specular[] = {1.0, 1.0, 1.0, 1.0};
  72. float mat_logo_shininess[] = {30.0};
  73.  
  74. float mat_holder_base_ambient[] = {0.0, 0.0, 0.0, 1.0};
  75. float mat_holder_base_diffuse[] = {0.6, 0.6, 0.6, 1.0};
  76. float mat_holder_base_specular[] = {0.8, 0.8, 0.8, 1.0};
  77. float mat_holder_base_shininess[] = {30.0};
  78.  
  79. float mat_holder_rings_ambient[] = { 0.0,0.0,0.0,1.0 };
  80. float mat_holder_rings_diffuse[] = { 0.9,0.8,0.0,1.0 };
  81. float mat_holder_rings_specular[] = { 1.0,1.0,1.0,1.0 };
  82. float mat_holder_rings_shininess[] = { 30.0 };
  83.  
  84. float mat_hemisphere_ambient[] = {0.0, 0.0, 0.0,1.0 };
  85. float mat_hemisphere_diffuse[] = {1.0, 0.2, 0.2,1.0 };
  86. float mat_hemisphere_specular[] = {0.5, 0.5, 0.5,1.0 };
  87. float mat_hemisphere_shininess[] = {20.0};
  88.  
  89. GLubyte stipple[32*32];
  90.  
  91. typedef float vector[3];
  92. typedef vector parameter[4];
  93.  
  94. /*
  95.  * Function definitions
  96.  */
  97. void initialize(void);
  98. void resize_window(int w, int h);
  99. void build_table(void);
  100. parameter *calc_spline_params(vector *ctl_pts, int n);
  101. void calc_spline(vector v, parameter *params, float current_time);
  102. void normalize(vector v);
  103. float dot(vector v1, vector v2);
  104. void draw_table(void);
  105. void draw_logo_shadow(void);
  106. void draw_hemisphere(void);
  107. void draw_logo(void);
  108. void draw_under_table(void);
  109. void draw_i(void);
  110. void draw_d(void);
  111. void draw_e(void);
  112. void draw_a(void);
  113. void draw_s(void);
  114. void draw_n(void);
  115. void draw_m(void);
  116. void draw_o(void);
  117. void draw_t(void);
  118.  
  119. int post_idle = 0;
  120. void idle(void);
  121. void do_post_idle(void);
  122. void display(void);
  123. void mouse(int b, int s, int x, int y);
  124. void keyboard(unsigned char c, int x, int y);
  125. void vis(int);
  126.  
  127. void init_materials(void) {
  128.   int x, y;
  129.  
  130.   /* Stipple pattern */
  131.   for (y = 0; y < 32; y++)
  132.     for (x = 0; x < 4; x++) 
  133.       stipple[y * 4 + x] = (y % 2) ? 0xaa : 0x55;
  134.  
  135.     glNewList(MAT_LOGO, GL_COMPILE); 
  136.     glMaterialfv(GL_FRONT, GL_AMBIENT, mat_logo_ambient); 
  137.     glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_logo_diffuse);
  138.     glMaterialfv(GL_FRONT, GL_SPECULAR, mat_logo_specular);
  139.     glMaterialfv(GL_FRONT, GL_SHININESS, mat_logo_shininess);
  140.     glEndList(); 
  141.  
  142.     glNewList( MAT_HOLDER_BASE, GL_COMPILE);
  143.     glMaterialfv(GL_FRONT, GL_AMBIENT, mat_holder_base_ambient); 
  144.     glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_holder_base_diffuse);
  145.     glMaterialfv(GL_FRONT, GL_SPECULAR, mat_holder_base_specular);
  146.     glMaterialfv(GL_FRONT, GL_SHININESS, mat_holder_base_shininess);
  147.     glEndList();
  148.  
  149.     glNewList(MAT_HOLDER_RINGS, GL_COMPILE); 
  150.     glMaterialfv(GL_FRONT, GL_AMBIENT, mat_holder_rings_ambient); 
  151.     glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_holder_rings_diffuse);
  152.     glMaterialfv(GL_FRONT, GL_SPECULAR, mat_holder_rings_specular);
  153.     glMaterialfv(GL_FRONT, GL_SHININESS, mat_holder_rings_shininess);
  154.     glEndList();
  155.  
  156.     glNewList(MAT_HEMISPHERE, GL_COMPILE); 
  157.     glMaterialfv(GL_FRONT, GL_AMBIENT, mat_hemisphere_ambient); 
  158.     glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_hemisphere_diffuse);
  159.     glMaterialfv(GL_FRONT, GL_SPECULAR, mat_hemisphere_specular);
  160.     glMaterialfv(GL_FRONT, GL_SHININESS, mat_hemisphere_shininess);
  161.     glEndList();
  162.  
  163. }
  164.  
  165. void init_lights(void) {
  166.   static float ambient[] = { 0.1, 0.1, 0.1, 1.0 };
  167.   static float diffuse[] = { 0.5, 1.0, 1.0, 1.0 };
  168.   static float position[] = { 90.0, 90.0, 150.0, 0.0 };
  169.   
  170.   glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
  171.   glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
  172.   glLightfv(GL_LIGHT0, GL_POSITION, position);
  173.  
  174.   glLightfv (GL_LIGHT1, GL_AMBIENT, light1_ambient);
  175.   glLightfv (GL_LIGHT1, GL_SPECULAR, light1_lcolor);
  176.   glLightfv (GL_LIGHT1, GL_DIFFUSE, light1_lcolor);
  177.   glLightfv (GL_LIGHT1, GL_POSITION, light1_position);
  178.     
  179.   glLightfv (GL_LIGHT2, GL_AMBIENT, light2_ambient);
  180.   glLightfv (GL_LIGHT2, GL_SPECULAR, light2_lcolor);
  181.   glLightfv (GL_LIGHT2, GL_DIFFUSE, light2_lcolor);
  182.   glLightfv (GL_LIGHT2, GL_POSITION, light2_position);
  183.  
  184.   glLightfv (GL_LIGHT3, GL_AMBIENT, light3_ambient);
  185.   glLightfv (GL_LIGHT3, GL_SPECULAR, light3_lcolor);
  186.   glLightfv (GL_LIGHT3, GL_DIFFUSE, light3_lcolor);
  187.   glLightfv (GL_LIGHT3, GL_POSITION, light3_position);
  188.   
  189.   glLightModelfv (GL_LIGHT_MODEL_LOCAL_VIEWER, lmodel_LVW);
  190.   glLightModelfv (GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
  191. }
  192.  
  193. short dev, val;
  194.  
  195. float current_time=0.0;
  196. float hold_time=0.0;        /* Used when auto-running */
  197.  
  198. float tmplight[] = {
  199.     GL_POSITION, 0.0, 0.0, 0.0, 0.0, 
  200. };
  201.  
  202. GLfloat tv[4][4] = {
  203.   {1.0, 0.0, 0.0, 0.0},
  204.   {0.0, 1.0, 0.0, -1.0},
  205.   {0.0, 0.0, 1.0, 0.0},
  206.   {0.0, 0.0, 0.0, 0.0},
  207. };
  208.  
  209. #define TABLERES 12
  210.  
  211. float pcr, pcg, pcb, pca;
  212.  
  213. vector table_points[TABLERES+1][TABLERES+1];
  214. int tablecolors[TABLERES+1][TABLERES+1];
  215.  
  216. vector paper_points[4] = {
  217.     {-0.8, 0.0, 0.4},
  218.     {-0.2, 0.0, -1.4},
  219.     {1.0, 0.0, -1.0},
  220.     {0.4, 0.0, 0.8},
  221. };
  222.  
  223. float dot(vector, vector);
  224.  
  225. #define TIME 15
  226. #define START_TIME 0.6
  227.  
  228. vector light_pos_ctl[] = {
  229.  
  230.     {0.0, 1.8, 0.0},
  231.     {0.0, 1.8, 0.0},
  232.     {0.0, 1.6, 0.0},
  233.  
  234.     {0.0, 1.6, 0.0},
  235.     {0.0, 1.6, 0.0},
  236.     {0.0, 1.6, 0.0},
  237.     {0.0, 1.4, 0.0},
  238.  
  239.     {0.0, 1.3, 0.0},
  240.     {-0.2, 1.5, 2.0},
  241.     {0.8, 1.5, -0.4},
  242.     {-0.8, 1.5, -0.4},
  243.  
  244.     {0.8, 2.0, 1.0},
  245.     {1.8, 5.0, -1.8},
  246.     {8.0, 10.0, -4.0},
  247.     {8.0, 10.0, -4.0},
  248.     {8.0, 10.0, -4.0},
  249. };
  250.  
  251. vector logo_pos_ctl[] = {
  252.  
  253.     {0.0, -0.5, 0.0},
  254.  
  255.     {0.0, -0.5, 0.0},
  256.     {0.0, -0.5, 0.0},
  257.  
  258.     {0.0, -0.5, 0.0},
  259.     {0.0, -0.5, 0.0},
  260.     {0.0, -0.5, 0.0},
  261.     {0.0, 0.0, 0.0},
  262.  
  263.     {0.0, 0.6, 0.0},
  264.     {0.0, 0.75, 0.0},
  265.     {0.0, 0.8, 0.0},
  266.     {0.0, 0.8, 0.0},
  267.  
  268.     {0.0, 0.5, 0.0},
  269.     {0.0, 0.5, 0.0},
  270.     {0.0, 0.5, 0.0},
  271.     {0.0, 0.5, 0.0},
  272.     {0.0, 0.5, 0.0},
  273. };
  274.  
  275.  
  276. vector logo_rot_ctl[] = {
  277.  
  278.     {0.0, 0.0, -18.4},
  279.  
  280.     {0.0, 0.0, -18.4},
  281.     {0.0, 0.0, -18.4},
  282.  
  283.     {0.0, 0.0, -18.4},
  284.     {0.0, 0.0, -18.4},
  285.     {0.0, 0.0, -18.4},
  286.     {0.0, 0.0, -18.4},
  287.     {0.0, 0.0, -18.4},
  288.  
  289. /*    {90.0, 0.0, -90.0},
  290.     {180.0, 180.0, 90.0}, */
  291.     {240.0, 360.0, 180.0},
  292.     {90.0, 180.0, 90.0},
  293.  
  294.     {11.9, 0.0, -18.4},
  295.     {11.9, 0.0, -18.4},
  296.     {11.9, 0.0, -18.4},
  297.     {11.9, 0.0, -18.4},
  298.     {11.9, 0.0, -18.4},
  299. };
  300.  
  301.  
  302. vector view_from_ctl[] = {
  303.  
  304.     {-1.0, 1.0, -4.0},
  305.  
  306.     {-1.0, -3.0, -4.0},    /* 0 */
  307.     {-3.0, 1.0, -3.0},    /* 1 */
  308.  
  309.     {-1.8, 2.0, 5.4},    /* 2 */
  310.     {-0.4, 2.0, 1.2},    /* 3 */
  311.     {-0.2, 1.5, 0.6},    /* 4 */
  312.     {-0.2, 1.2, 0.6},    /* 5 */
  313.  
  314.     {-0.8, 1.0, 2.4},    /* 6 */
  315.     {-1.0, 2.0, 3.0},    /* 7 */
  316.     {0.0, 4.0, 3.6},    /* 8 */
  317.     {-0.8, 4.0, 1.2},    /* 9 */
  318.  
  319.     {-0.2, 3.0, 0.6},    /* 10 */
  320.     {-0.1, 2.0, 0.3},    /* 11 */
  321.     {-0.1, 2.0, 0.3},    /* 12 */
  322.     {-0.1, 2.0, 0.3},    /* 13 */
  323.     {-0.1, 2.0, 0.3},    /* 13 */
  324.  
  325.  
  326. };
  327.  
  328. vector view_to_ctl[] = {
  329.  
  330.     {-1.0, 1.0, 0.0},
  331.  
  332.     {-1.0, -3.0, 0.0},
  333.     {-1.0, 1.0, 0.0},
  334.  
  335.     {0.1, 0.0, -0.3},
  336.     {0.1, 0.0, -0.3},
  337.     {0.1, 0.0, -0.3},
  338.     {0.0, 0.2, 0.0},
  339.  
  340.     {0.0, 0.6, 0.0},
  341.     {0.0, 0.8, 0.0},
  342.     {0.0, 0.8, 0.0},
  343.     {0.0, 0.8, 0.0},
  344.  
  345.     {0.0, 0.8, 0.0},
  346.     {0.0, 0.8, 0.0},
  347.     {0.0, 0.8, 0.0},
  348.     {0.0, 0.8, 0.0},
  349.     {0.0, 0.8, 0.0},
  350.  
  351. };
  352.  
  353.  
  354. vector view_from, view_to, light_pos, logo_pos, logo_rot;
  355.  
  356. parameter *view_from_spline, *view_to_spline,
  357.       *light_pos_spline, *logo_pos_spline,
  358.       *logo_rot_spline;
  359.  
  360. parameter *calc_spline_params(vector *, int);
  361.  
  362. double a3, a4;
  363.  
  364. void ideas_usage(void)
  365. {
  366.   fprintf(stderr, "Usage: ideas [-a] [-m] [-d] -s{1-4}\n");
  367.   fprintf(stderr, "Press ESC to quit, 1-4 to control speed, any other key\n");
  368.   fprintf(stderr, "to pause.\n");
  369. }
  370.  
  371.   int auto_run;        /* If set, then automatically run forever */
  372.   float new_speed;    /* Set new animation speed? */
  373.   int timejerk;        /* Set to indicate time jerked! (menu pulled down) */
  374.   int paused = 0;    /* Paused? */
  375.   int right = 0;    /* Draw right eye? */
  376.   int resetclock;    /* Reset the clock? */
  377.   float timeoffset;    /* Used to compute timing */
  378.   struct timeval start;
  379.  
  380. void main(int argc, char **argv)
  381. {
  382.   int i;
  383.  
  384.   glutInitWindowSize(300, 240);
  385.   glutInit(&argc, argv);
  386.  
  387.   auto_run = 0;    /* Don't automatically run forever */
  388.   /* .4 spline distance per second by default */
  389.   move_speed = SPEED_MEDIUM;
  390.   new_speed = SPEED_MEDIUM;
  391.   timeoffset = START_TIME;
  392.   
  393.   for (i = 1; i < argc; i++) {
  394.     if (argv[i][0] != '-') {
  395.       break;
  396.     }
  397.     
  398.     switch(argv[i][1]) {
  399.     case 'a':    /* Keep running forever */
  400.       auto_run = 1;
  401.       break;
  402.     case 'm':    /* Multisample */
  403.       multisample = 1;
  404.       break;
  405.     case 'd':    /* Single buffer */
  406.       doublebuffer = 0;
  407.       break;
  408.     case 's':
  409.       switch(argv[i][2]) {
  410.       case '1':
  411.     move_speed = new_speed = SPEED_SLOW;
  412.     break;
  413.       case '2':
  414.     move_speed = new_speed = SPEED_MEDIUM;
  415.     break;
  416.       case '3':
  417.     move_speed = new_speed = SPEED_FAST;
  418.     break;
  419.       case '4':
  420.     move_speed = new_speed = SPEED_SUPER_FAST;
  421.     break;
  422.       }
  423.       break;
  424.     default:
  425.       ideas_usage();
  426.       break;
  427.     }
  428.   }
  429.   
  430.   initialize();
  431.   
  432.   current_time = timeoffset;
  433.   resetclock = 1;
  434.   timejerk = 0;
  435.   glutMainLoop();
  436. }
  437.  
  438. void idle(void) 
  439. {
  440.     if ((current_time) > (TIME*1.0)-3.0) {
  441.       if (auto_run) {
  442.     hold_time += current_time - (TIME - 3.001);
  443.     if (hold_time > 3.0) {    /* 3 second hold */
  444.       hold_time = 0.0;
  445.       resetclock = 1;
  446.     }
  447.       } else {
  448.         if(!resetclock) glutIdleFunc(NULL);
  449.       }
  450.       current_time = (TIME*1.0)-3.001;
  451.     } else {
  452.        post_idle = 1;
  453.     }
  454.     glutPostRedisplay();
  455. }
  456.  
  457. void
  458. mouse(int b, int s, int x, int y)
  459. {
  460.    if(b == GLUT_LEFT_BUTTON && s == GLUT_DOWN) {
  461.       resetclock = 1;
  462.       paused = 0;
  463.       glutIdleFunc(idle);
  464.    }
  465. }
  466.  
  467. void
  468. keyboard(unsigned char c, int x, int y)
  469. {
  470.    switch(c) {
  471.    case 27:
  472.       exit(0);
  473.       break;
  474.    case '1':
  475.       new_speed = SPEED_SLOW;
  476.       break;
  477.    case '2':
  478.       new_speed = SPEED_MEDIUM;
  479.       break;
  480.    case '3':
  481.       new_speed = SPEED_FAST;
  482.       break;
  483.    case '4':
  484.       new_speed = SPEED_SUPER_FAST;
  485.       break;
  486.    default:
  487.       if (paused) timejerk = 1;
  488.       paused = ~paused;
  489.       if(paused) {
  490.      glutIdleFunc(NULL);
  491.       } else {
  492.      glutIdleFunc(idle);
  493.       }
  494.    }
  495. }
  496.  
  497. void
  498. vis(int visible)
  499. {
  500.   if (visible == GLUT_VISIBLE) {
  501.       if(!paused) glutIdleFunc(idle);
  502.       do_post_idle();
  503.   } else {
  504.       if(!paused) glutIdleFunc(NULL);
  505.   }
  506. }
  507.  
  508. void display(void)
  509. {
  510.   float x, y, z, c;
  511.  
  512.     calc_spline(view_from, view_from_spline, current_time);
  513.     calc_spline(view_to, view_to_spline, current_time);
  514.     calc_spline(light_pos, light_pos_spline, current_time);
  515.     calc_spline(logo_pos, logo_pos_spline, current_time);
  516.     calc_spline(logo_rot, logo_rot_spline, current_time);
  517.     
  518.     tmplight[1] = light_pos[X] - logo_pos[X];
  519.     tmplight[2] = light_pos[Y] - logo_pos[Y];
  520.     tmplight[3] = light_pos[Z] - logo_pos[Z];
  521.     
  522.     glNewList(LIGHT_TMP, GL_COMPILE); 
  523.     glMaterialf(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, * tmplight); 
  524.     glEndList();
  525.     
  526.     tv[0][0] = tv[1][1] = tv[2][2] = light_pos[Y];
  527.     
  528.     glColor3ub(0,  0,  0);
  529.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
  530.     
  531.     /*
  532.      * SHADOW
  533.      */
  534.     glMatrixMode(GL_MODELVIEW);
  535.     glLoadIdentity();
  536.     gluLookAt(view_from[X], view_from[Y], view_from[Z], 
  537.           view_to[X], view_to[Y], view_to[Z],
  538.           0.0, 1.0, 0.0);
  539.     
  540.     if (view_from[Y] > 0.0) draw_table();
  541.  
  542.     glEnable(GL_CULL_FACE); 
  543.     glDisable(GL_DEPTH_TEST); 
  544.  
  545.     if (logo_pos[Y] < 0.0) {
  546.       
  547.       if (logo_pos[Y]>-0.33) {
  548.     /* We're emerging from the table */
  549.     c = 1.0 - (logo_pos[Y]) / -0.33;
  550.     pca /= 4.0;
  551.     glColor3ub((int)(128.0*(1.0-c)*0.5 + 255.0*pca*c),
  552.            (int)(102.0*(1.0-c)*0.5 + 255.0*pca*c),
  553.            (int)(179.0*(1.0-c)*0.5 + 200.0*pca*c));
  554.       } else {
  555.     /* Still under table */
  556.     glColor3ub(128/2,  102/2,  179/2);
  557.       }
  558.       
  559.       glPushMatrix();
  560.       glScalef(0.04,  0.0,  0.04);
  561.       glRotatef(0.1 * (-900), 1.0, 0.0, 0.0);
  562.       glRotatef(0.1 * ((int)(10.0*logo_rot[Z])), 0.0, 0.0, 1.0);
  563.       glRotatef(0.1 * ((int)(10.0*logo_rot[Y])), 0.0, 1.0, 0.0);
  564.       glRotatef(0.1 * ((int)(10.0*logo_rot[X])), 1.0, 0.0, 0.0);
  565.       glRotatef(0.1 * (353), 1.0, 0.0, 0.0);
  566.       glRotatef(0.1 * (450), 0.0, 1.0, 0.0);
  567.       draw_logo_shadow();
  568.       glPopMatrix();
  569.     }
  570.     
  571.     if (logo_pos[Y] > 0.0) {
  572.       glPushMatrix();
  573.       if (logo_pos[Y]<0.33) {
  574.     pca /= 4.0;
  575.     c = 1.0 - (logo_pos[Y])/0.33;
  576.     glColor3ub((int)(255.0*pca*c),
  577.            (int)(255.0*pca*c),
  578.            (int)(200.0*pca*c));
  579.       } else {
  580.     glColor3ub(0, 0, 0);
  581.       }
  582.       
  583.       glTranslatef(light_pos[X],  light_pos[Y],  light_pos[Z]);
  584.       glMultMatrixf(&tv[0][0]);
  585.       glTranslatef(-light_pos[X]+logo_pos[X],
  586.            -light_pos[Y]+logo_pos[Y],
  587.            -light_pos[Z]+logo_pos[Z]);
  588.       glScalef(0.04,  0.04,  0.04);
  589.       glRotatef (0.1 * (-900), 1.0, 0.0, 0.0);
  590.       glRotatef (0.1 * ((int)(10.0*logo_rot[Z])), 0.0, 0.0, 1.0);
  591.       glRotatef (0.1 * ((int)(10.0*logo_rot[Y])), 0.0, 1.0, 0.0);
  592.       glRotatef (0.1 * ((int)(10.0*logo_rot[X])), 1.0, 0.0, 0.0);
  593.       glRotatef (0.1 * (353), 1.0, 0.0, 0.0);
  594.       glRotatef (0.1 * (450), 0.0, 1.0, 0.0);
  595.  
  596.  
  597.       glEnable(GL_POLYGON_STIPPLE);
  598.       glPolygonStipple(stipple);
  599.       draw_logo_shadow();
  600.       glDisable(GL_POLYGON_STIPPLE);
  601.       glPopMatrix();
  602.     }
  603.     /*
  604.      * DONE SHADOW 
  605.      */
  606.  
  607.  
  608.     glEnable(GL_DEPTH_TEST);
  609.     glDisable(GL_CULL_FACE);
  610.     glEnable(GL_LIGHTING);
  611.  
  612.     glMatrixMode(GL_PROJECTION);
  613.     glLoadIdentity();
  614.     gluPerspective(.1*(450),  5.0/4.0,  0.5,  20.0);
  615.     glMatrixMode(GL_MODELVIEW);
  616.     glLoadMatrixf(&idmat[0][0]); 
  617.     
  618.     gluLookAt(view_from[X],  view_from[Y],  view_from[Z],
  619.           view_to[X],  view_to[Y],  view_to[Z], 
  620.           0.0, 1.0, 0.0);
  621.     
  622.     glCallList( MAT_HOLDER_RINGS); 
  623.     
  624.     glPushMatrix();
  625.     glTranslatef(light_pos[X],  light_pos[Y],  light_pos[Z]);
  626.     glScalef(0.1,  0.1,  0.1);
  627.     
  628.     x = light_pos[X] - logo_pos[X];
  629.     y = light_pos[Y] - logo_pos[Y];
  630.     z = light_pos[Z] - logo_pos[Z];
  631.     
  632.     if (x!=0.0) {
  633.       a3 = -atan2(z, x)*10.0 RAD;
  634.     } else a3 = 0.0;
  635.     
  636.     a4 = -atan2(sqrt(x*x + z*z), y)*10.0 RAD;
  637.     
  638.     glRotatef (0.1 * ((int)a3), 0.0, 1.0, 0.0);
  639.     glRotatef (0.1 * ((int)a4), 0.0, 0.0, 1.0);
  640.     glRotatef (0.1 * (-900), 1.0, 0.0, 0.0);
  641.     
  642.     glEnable(GL_LIGHT2);
  643.     glEnable(GL_LIGHT3);
  644.     glCallList(MAT_HEMISPHERE);
  645.     glEnable(GL_NORMALIZE);
  646.     draw_hemisphere();
  647.     glDisable(GL_NORMALIZE);
  648.     glPopMatrix();
  649.  
  650.     glDisable(GL_LIGHT2);
  651.     glDisable(GL_LIGHT3); 
  652.     glEnable(GL_LIGHT1);
  653.     glLightfv(GL_LIGHT1, GL_POSITION, light_pos);
  654.     
  655.     if (logo_pos[Y] > -0.33) {
  656.  
  657.       glCallList(MAT_LOGO);
  658.     
  659.       glPushMatrix();
  660.       glTranslatef(logo_pos[X],  logo_pos[Y],  logo_pos[Z]);
  661.       glScalef(0.04,  0.04,  0.04);
  662.       glRotatef (0.1 * (-900), 1.0, 0.0, 0.0);
  663.       glRotatef (0.1 * ((int)(10.0*logo_rot[Z])), 0.0, 0.0, 1.0);
  664.       glRotatef (0.1 * ((int)(10.0*logo_rot[Y])), 0.0, 1.0, 0.0);
  665.       glRotatef (0.1 * ((int)(10.0*logo_rot[X])), 1.0, 0.0, 0.0);
  666.       glRotatef (0.1 * (353), 1.0, 0.0, 0.0);
  667.       glRotatef (0.1 * (450), 0.0, 1.0, 0.0);
  668.       glEnable(GL_LIGHTING);
  669.       draw_logo();
  670.       glPopMatrix();
  671.     }
  672.     
  673.     if (view_from[Y] < 0.0) draw_under_table();
  674.     
  675.     glutSwapBuffers();
  676.  
  677.     if(post_idle) do_post_idle();
  678. }
  679.  
  680. void do_post_idle(void)
  681. {
  682.   struct timeval current;
  683.   float timediff;    
  684.  
  685.     /* Time jerked -- adjust clock appropriately */
  686.     if (timejerk) {
  687.       timejerk = 0;
  688.       timeoffset = current_time;
  689.       gettimeofday(&start, NULL);
  690.     }
  691.     
  692.     /* Reset our timer */
  693.     if (resetclock) {
  694.       resetclock = 0;
  695.       paused = 0;
  696.       timeoffset = START_TIME;
  697.       gettimeofday(&start, NULL);
  698.     }
  699.     
  700.     /* Compute new time */
  701.     gettimeofday(¤t, NULL);
  702.     timediff = (current.tv_sec - start.tv_sec) + 
  703.       (current.tv_usec - start.tv_usec) / 1000000.0;
  704.     if (!paused) {
  705.        current_time = timediff * move_speed + timeoffset;
  706.     }
  707.     
  708.     /* Adjust to new speed */
  709.     if (new_speed != move_speed) {
  710.       move_speed = new_speed;
  711.       timeoffset = current_time;
  712.       gettimeofday(&start, NULL);
  713.     }
  714.     post_idle = 0;
  715. }
  716.  
  717. void resize_window(int w, int h) 
  718. {
  719.   glMatrixMode(GL_PROJECTION);
  720.   glLoadIdentity();
  721.   gluPerspective (45.0, 5.0/4.0, 0.5, 20.0); 
  722.   glMatrixMode(GL_MODELVIEW);
  723.   glLoadIdentity();
  724.   glViewport(0, 0, w, h);
  725. }
  726.  
  727. void initialize(void)
  728. {
  729.     int attr;
  730.  
  731.     attr = doublebuffer ? RGBA_DB_attributes : RGBA_SB_attributes;
  732.     glutInitDisplayMode(attr);
  733.     glutCreateWindow("Ideas");
  734.  
  735.     if (multisample) glEnable(GL_POLYGON_SMOOTH); 
  736.     
  737.     init_lights();
  738.     init_materials();
  739.  
  740.     build_table();
  741.  
  742.     view_from_spline = calc_spline_params(view_from_ctl, TIME);
  743.     view_to_spline = calc_spline_params(view_to_ctl, TIME);
  744.     light_pos_spline = calc_spline_params(light_pos_ctl, TIME);
  745.     logo_pos_spline = calc_spline_params(logo_pos_ctl, TIME);
  746.     logo_rot_spline = calc_spline_params(logo_rot_ctl, TIME);
  747.  
  748.     glutReshapeFunc(resize_window);
  749.     glutDisplayFunc(display);
  750.     glutMouseFunc(mouse);
  751.     glutKeyboardFunc(keyboard);
  752.     glutVisibilityFunc(vis);
  753.  
  754.     glMatrixMode(GL_MODELVIEW);
  755. }
  756.  
  757.  
  758. void build_table(void) 
  759. {
  760.     float i, j;
  761.  
  762.     for (j=0.0; j<=TABLERES*1.0; j+=1.0) {
  763.     for (i=0.0; i<=TABLERES*1.0; i+=1.0) {
  764.         table_points[(int)j][(int)i][Z] = (i-TABLERES*1.0/2.0)/2.0;
  765.         table_points[(int)j][(int)i][X] = (j-TABLERES*1.0/2.0)/2.0;
  766.         table_points[(int)j][(int)i][Y] = 0.0;
  767.     }
  768.     }
  769. }
  770.  
  771.  
  772. void draw_table(void)
  773. {
  774.     float c;
  775.     int i, j;
  776.     int k, l;
  777.     float ov[3], lv[3];
  778.  
  779.     glDisable(GL_DEPTH_TEST);
  780.     glDisable(GL_LIGHTING);
  781.  
  782.     ov[X] = light_pos[X]-logo_pos[X];
  783.     ov[Y] = light_pos[Y]-logo_pos[Y];
  784.     ov[Z] = light_pos[Z]-logo_pos[Z];
  785.  
  786.     normalize(ov);
  787.  
  788.     for (j=0; j<=TABLERES; j++) {
  789.       for (i=0; i<=TABLERES; i++) {
  790.     lv[X] = light_pos[X] - table_points[j][i][X];
  791.     lv[Y] = light_pos[Y] - table_points[j][i][Y];
  792.     lv[Z] = light_pos[Z] - table_points[j][i][Z];
  793.     normalize(lv);
  794.     if ((c = dot(lv, ov))<0.0) c = 0.0;
  795.     c = c * c * c * lv[Y] * 255.0;
  796.     /* fade */
  797.     if ((current_time>TIME-5.0) && (current_time<TIME-3.0)) 
  798.       c *= 1.0 - (current_time-(TIME-5.0)) * 0.5;
  799.     
  800.     tablecolors[j][i] = (int)c;
  801.       }
  802.     }
  803.     
  804.     
  805.     for (l=0; l<TABLERES; l++) {
  806.       
  807.       glBegin(GL_TRIANGLE_STRIP);
  808.       for (k=0; k<=TABLERES; k++) {
  809.     glColor3ub(tablecolors[l][k],
  810.            tablecolors[l][k],
  811.            tablecolors[l][k]);
  812.     glVertex3fv(table_points[l][k]);
  813.  
  814.     glColor3ub(tablecolors[l+1][k],
  815.            tablecolors[l+1][k], 
  816.            tablecolors[l+1][k]);
  817.     glVertex3fv(table_points[l+1][k]);
  818.     
  819.       }
  820.     glEnd();
  821.     }
  822.  
  823.     if (logo_pos[Y]>-0.33 && logo_pos[Y]<0.33) {
  824.     glEnable(GL_DEPTH_TEST);
  825.     }
  826.  
  827.     pca = 0.0;
  828.     glBegin(GL_POLYGON);
  829.     for (i=0; i<4; i++) {
  830.       lv[X] = light_pos[X] - paper_points[i][X];
  831.       lv[Y] = light_pos[Y] - paper_points[i][Y];
  832.       lv[Z] = light_pos[Z] - paper_points[i][Z];
  833.       normalize(lv);
  834.       if ((c = dot(lv, ov))<0.0) c = 0.0;
  835.       c = c * c * c * lv[Y];
  836.       /* fade */
  837.       if ((current_time>TIME-5.0) && (current_time<TIME-3.0)) 
  838.     c *= 1.0 - (current_time-(TIME-5.0)) * 0.5;
  839.       
  840.       pcr = c * 255; pcg = c * 255; pcb = c * 200;
  841.       pca += c;
  842.       glColor3ub((int)pcr,  (int)pcg,  (int)pcb);
  843.       glVertex3fv(paper_points[i]);
  844.     }
  845.     glEnd();
  846.  
  847.     glPushMatrix();
  848.     glRotatef (0.1 * (-184), 0.0, 1.0, 0.0);
  849.     glTranslatef(-0.3, 0.0, -0.8);
  850.     glRotatef (0.1 * (-900), 1.0, 0.0, 0.0);
  851.     glScalef(0.015, 0.015, 0.015);
  852.  
  853.  
  854.     if (current_time>TIME*1.0-5.0) {
  855.     c = (current_time-(TIME*1.0-5.0))/2.0;
  856.     glColor3ub((int)(c*255.0),  (int)(c*255.0),  (int)(c*255.0));
  857.     } else glColor3ub(0,  0,  0);
  858.  
  859.     glDisable(GL_DEPTH_TEST);
  860.  
  861.     draw_i();
  862.     glTranslatef(3.0,  0.0,  0.0);
  863.  
  864.     draw_d();
  865.     glTranslatef(6.0,  0.0,  0.0);
  866.  
  867.     draw_e();
  868.     glTranslatef(5.0,  0.0,  0.0);
  869.  
  870.     draw_a();
  871.     glTranslatef(6.0,  0.0,  0.0);
  872.  
  873.     draw_s();
  874.     glTranslatef(10.0,  0.0,  0.0);
  875.  
  876.     draw_i();
  877.     glTranslatef(3.0,  0.0,  0.0);
  878.  
  879.     draw_n();
  880.     glTranslatef(-31.0,  -13.0,  0.0);
  881.  
  882.     draw_m();
  883.     glTranslatef(10.0,  0.0,  0.0);
  884.  
  885.     draw_o();
  886.     glTranslatef(5.0,  0.0,  0.0);
  887.  
  888.     draw_t();
  889.     glTranslatef(4.0,  0.0,  0.0);
  890.  
  891.     draw_i();
  892.     glTranslatef(3.5,  0.0,  0.0);
  893.  
  894.     draw_o();
  895.     glTranslatef(5.0,  0.0,  0.0);
  896.  
  897.     draw_n();
  898.  
  899.     glPopMatrix();
  900.  
  901. }
  902.  
  903.  
  904.  
  905. void draw_under_table(void) 
  906. {
  907.     int k, l;
  908.  
  909.     if(FALSE) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
  910.  
  911.  
  912.     glColor3ub(0,  0,  0);
  913.  
  914.     for (l=0; l<TABLERES; l++) {
  915.  
  916.     glBegin(GL_TRIANGLE_STRIP);
  917.     for (k=0; k<=TABLERES; k++) {
  918.  
  919.         glVertex3fv(table_points[l][k]);
  920.         glVertex3fv(table_points[l+1][k]);
  921.  
  922.     }
  923.     glEnd();
  924.     }
  925.  
  926.     if(TRUE) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
  927.  
  928. }
  929.  
  930.  
  931.  
  932. void calc_spline(vector v, parameter *params, float current_time)
  933. {
  934.  
  935.     float t;
  936.     int i;
  937.  
  938.     t = current_time - (float)((int)current_time);
  939.  
  940.     for (i=0; i<3; i++) {
  941.  
  942.  
  943.     v[i] = params[(int)current_time][3][i] +
  944.            params[(int)current_time][2][i] * t +
  945.            params[(int)current_time][1][i] * t * t +
  946.            params[(int)current_time][0][i] * t * t * t;
  947.     }
  948.  
  949. }
  950.  
  951.  
  952. parameter *calc_spline_params(vector *ctl_pts, int n)
  953. {
  954.  
  955.     int i, j;
  956.     parameter *params;
  957.  
  958.     if (n<4) {
  959.     fprintf(stderr,
  960.         "calc_spline_params: not enough control points\n");
  961.     return (NULL);
  962.     }
  963.  
  964.     params = (parameter *)malloc(sizeof(parameter) * (n-3));
  965.  
  966.     for (i=0; i<n-3; i++) {
  967.  
  968.     for (j=0; j<3; j++) {
  969.  
  970.         params[i][3][j] = ctl_pts[i+1][j];
  971.         params[i][2][j] = ctl_pts[i+2][j] - ctl_pts[i][j];
  972.         params[i][1][j] =  2.0 * ctl_pts[i][j] +
  973.                   -2.0 * ctl_pts[i+1][j] +
  974.                    1.0 * ctl_pts[i+2][j] +
  975.                   -1.0 * ctl_pts[i+3][j];
  976.         params[i][0][j] = -1.0 * ctl_pts[i][j] +
  977.                    1.0 * ctl_pts[i+1][j] +
  978.                   -1.0 * ctl_pts[i+2][j] +
  979.                    1.0 * ctl_pts[i+3][j];
  980.  
  981.     }
  982.     }
  983.  
  984.     return (params);
  985. }
  986.  
  987.  
  988. void normalize(vector v)
  989. {
  990.     float r;
  991.  
  992.     r = sqrt(v[X]*v[X] + v[Y]*v[Y] + v[Z]*v[Z]);
  993.  
  994.     v[X] /= r;
  995.     v[Y] /= r;
  996.     v[Z] /= r;
  997. }
  998.  
  999.  
  1000. float dot(vector v1, vector v2)
  1001. {
  1002.     return v1[X]*v2[X]+v1[Y]*v2[Y]+v1[Z]*v2[Z];
  1003. }
  1004.  
  1005.